#ifndef _DEBUG_BUFFER_H_
#define _DEBUG_BUFFER_H_

template<class charT>
struct cDebugFunction
{
    typedef void cResultType;                           
    typedef const charT * const cFirstArgumentType;    
    typedef const charT * const cSecondArgumentType;   
};


template
<
    class charT,                                    // character type
    class logfunction,                              // logfunctor type
    class traits = std::char_traits<charT>          // character traits
>
class cDebugBuffer : public std::basic_streambuf<charT, traits>
{
	typedef std::basic_string<charT, traits> cStringType;   
public:
	virtual ~cDebugBuffer() {};
    void SetContext(const cStringType &lContext)
	{
        mContext = lContext;
    }
protected:
    virtual typename traits::int_type overflow (typename traits::int_type c)
	{
		if (!traits::eq_int_type(c, traits::eof())) // if current character is not EOF 
        {
            mBuffer += traits::to_char_type(c);     // add current character to buffer
            if (c == traits::to_int_type('\n'))     // if current character is a new line 
                sync();                             // flush buffer			
        }
        return traits::not_eof(c);
	}
    virtual int sync()
	{
        if (!mBuffer.empty())   // if characters in the buffer  
            SendToDebugLog();   // send them to the debuglogfunction 
        mBuffer.clear();        // empty buffer
        return 0;
    }
private:
    cStringType mBuffer, mContext;
    logfunction mFunction;
    void SendToDebugLog()
	{
        mFunction(mContext.c_str(), mBuffer.c_str());   // send context and message 
    }
};

#endif